package com.iot08.api.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.iot08.api.config.redis.RedisAccountService;
import com.iot08.api.config.redis.RedisVideoService;
import com.iot08.api.controller.base.BaseController;
import com.iot08.api.service.MessageStatsService;
import com.iot08.api.service.UserKeyActionService;
import com.iot08.api.utils.buckettool.BaseBucketTool;
import com.iot08.api.utils.ContentSecurityUtil;
import com.iot08.api.utils.SpringContextUtil;
import com.iot08.common.utils.response.ResponseMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Arrays;


/**
 * @version 1.0
 * @Description: 阿里云内容安全回调接口(语音 / 视频 审核)
 * @time: 2023/11/13 09:07
 * @author: Weichao
 */
@Slf4j
@RestController
@RequestMapping("getway")
public class AliContentSecurityBackAPIController extends BaseController {

    @Resource
    private RedisVideoService redisVideoService;

    @Resource
    private UserKeyActionService userKeyActionService;

    @Resource
    private MessageStatsService messageStatsService;


    @Resource
    private BaseBucketTool baseBucketTool;

    @Value("${contentSecurity.aliuid:}")
    private String aliuid;


    public static byte[] hashWithSHA256(String input) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(input.getBytes(StandardCharsets.UTF_8));
            return hash;
        } catch (Exception e) {
            log.error("SHA256 哈希加密出错:" + e.getMessage(), e);
        }
        return null;
    }

    public static String bytesToHex(byte[] hash) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : hash) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) hexString.append('0');
            hexString.append(hex);
        }
        return hexString.toString();
    }

    /**
     * 阿里云内容安全回调接口(语音/视频 审核)
     */
    @PostMapping("aliCSBack/audio")
    public ResponseMap aliCSBack_audio(@RequestBody String body, HttpServletRequest request) {
        String activeProfile = SpringContextUtil.getActiveProfile();


        if (activeProfile.contains("dev") || activeProfile.contains("local")) {
            /*
            body的内容
            原:
            checksum=d34c5ecc8915cee89753d02ef9e05d1054e4cc37fbd28c98665abe7621477f6a&content=%7B%22Code%22%3A200%2C%22Data%22%3A%7B%22SliceDetails%22%3A%5B%7B%22EndTime%22%3A8%2C%22EndTimestamp%22%3A1699931836136%2C%22Extend%22%3A%22%7B%5C%22riskTips%5C%22%3A%5C%22%E8%BF%9D%E7%A6%81_%E7%A6%81%E9%99%90%E5%94%AE%E8%BF%9D%E7%A6%81%E5%93%81%2C%E8%BF%9D%E7%A6%81_%E8%BF%9D%E7%A6%81%E8%8D%AF%E5%93%81%2C%E8%BF%9D%E7%A6%81_%E6%B6%89%E6%AF%92%5C%22%2C%5C%22riskWords%5C%22%3A%5C%22%E5%8F%AF%E5%8D%A1%E5%9B%A0%5C%22%7D%22%2C%22Labels%22%3A%22contraband%22%2C%22RiskTips%22%3A%22%E8%BF%9D%E7%A6%81_%E7%A6%81%E9%99%90%E5%94%AE%E8%BF%9D%E7%A6%81%E5%93%81%2C%E8%BF%9D%E7%A6%81_%E8%BF%9D%E7%A6%81%E8%8D%AF%E5%93%81%2C%E8%BF%9D%E7%A6%81_%E6%B6%89%E6%AF%92%22%2C%22RiskWords%22%3A%22%E5%8F%AF%E5%8D%A1%E5%9B%A0%22%2C%22StartTime%22%3A0%2C%22StartTimestamp%22%3A1699931828136%2C%22Text%22%3A%22%E5%96%82%E5%96%82%E5%96%82%E5%96%82%E5%96%82%E3%80%82%E6%B5%8B%E8%AF%95%E6%B5%8B%E8%AF%95%E5%8F%AF%E5%8D%A1%E5%9B%A0%E3%80%82%22%2C%22Url%22%3A%22http%3A%2F%2Foss-cip-shanghai.oss-cn-shanghai.aliyuncs.com%2Fcip-media%2Fvoice%2F04106e57b%2F1337978_as00000.wav%3FExpires%3D1699953428%26OSSAccessKeyId%3DLTAI5t6KYjFmqpFzteQWRo4j%26Signature%3D91h9FWQfLmvpwoMy%252B%252F1qIJMWi3o%253D%22%2C%22subTaskId%22%3A%22au_f_tX8kRL6YqluF5TT9zDyrlB-1yYLl9_sub_1%22%7D%5D%7D%2C%22Message%22%3A%22success+finished%22%2C%22RequestId%22%3A%22d3cddf79-7a05-4853-8117-5d0da1d59c02%22%7D&taskId=au_f_tX8kRL6YqluF5TT9zDyrlB-1yYLl9
            URL解码后:
            checksum=d34c5ecc8915cee89753d02ef9e05d1054e4cc37fbd28c98665abe7621477f6a&content={"Code":200,"Data":{"SliceDetails":[{"EndTime":8,"EndTimestamp":1699931836136,"Extend":"{\"riskTips\":\"违禁_禁限售违禁品,违禁_违禁药品,违禁_涉毒\",\"riskWords\":\"可卡因\"}","Labels":"contraband","RiskTips":"违禁_禁限售违禁品,违禁_违禁药品,违禁_涉毒","RiskWords":"可卡因","StartTime":0,"StartTimestamp":1699931828136,"Text":"喂喂喂喂喂。测试测试可卡因。","Url":"http://oss-cip-shanghai.oss-cn-shanghai.aliyuncs.com/cip-media/voice/04106e57b/1337978_as00000.wav?Expires=1699953428&OSSAccessKeyId=LTAI5t6KYjFmqpFzteQWRo4j&Signature=91h9FWQfLmvpwoMy%2B%2F1qIJMWi3o%3D","subTaskId":"au_f_tX8kRL6YqluF5TT9zDyrlB-1yYLl9_sub_1"}]},"Message":"success+finished","RequestId":"d3cddf79-7a05-4853-8117-5d0da1d59c02"}&taskId=au_f_tX8kRL6YqluF5TT9zDyrlB-1yYLl9
            * */
            log.info("阿里云 语音审核 回调接口: body:{} request:{}", body, request);

        }

        // 用"&"分割字符串，得到键值对数组
        String[] pairs = body.split("&");
        JSONObject bodyOB = new JSONObject();
        for (String pair : pairs) {
            String[] keyValue = pair.split("=");
            bodyOB.put(keyValue[0], keyValue[1]);
        }

        //校验checksum
        String checksum = bodyOB.getString("checksum");


        try {


            String seed = "jianyou";
            String encodedContent = bodyOB.getString("content");
            String decodedContent = URLDecoder.decode(encodedContent, "UTF-8");
//            String combined = aliuid + seed + encodedContent;
//            byte[] hash = hashWithSHA256(combined);
//            if(!checksum.equalsIgnoreCase(Arrays.toString(hash))){
//                log.error("checksum 校验不通过: content:{} ", encodedContent);
//                return ResponseMap.fail();
//            }
            JSONObject content = JSONObject.parseObject(decodedContent);
            /*
            content JSONObject 回调示例:
            {
                "Code": 200,
                "Data": {
                    "SliceDetails": [{
                        "EndTime": 6,
                        "EndTimestamp": 1699943086591,
                        "Extend": "{\"riskTips\":\"违禁_禁限售违禁品,违禁_违法犯罪,违禁_违禁药品,违禁_违禁商品or赌博平台,违禁_涉毒\",\"riskWords\":\"冰毒\"}",
                        "Labels": "contraband",
                        "RiskTips": "违禁_禁限售违禁品,违禁_违法犯罪,违禁_违禁药品,违禁_违禁商品or赌博平台,违禁_涉毒",
                        "RiskWords": "冰毒",
                        "StartTime": 0,
                        "StartTimestamp": 1699943080591,
                        "Text": "哈喽哈喽哈喽冰毒。",
                        "Url": "http://oss-cip-shanghai.oss-cn-shanghai.aliyuncs.com/cip-media/voice/0243e57b/1626871_as00000.wav?Expires=1699964680&OSSAccessKeyId=LTAI5t6KYjFmqpFzteQWRo4j&Signature=CE2kpze%2F8mh2AbLhGHdUWtANY10%3D",
                        "subTaskId": "au_f_Eaqw6JGVkHVyx20M8LTNKY-1yYO0S_sub_1"
                    }]
                },
                "Message": "success+finished",
                "RequestId": "7dfb430b-4708-4542-a5db-b016161e1454"
            }
            */

            String taskId = bodyOB.getString("taskId");
            //进行一下URL解码
            taskId = URLDecoder.decode(taskId, "UTF-8");

            String value = redisVideoService.get(ContentSecurityUtil.ChatAudioKey + taskId);
            if (value == null) {
                log.error("阿里云内容安全回调接口-语音, taskId:{} 找不到Redis的记录", taskId);
                return ResponseMap.success();
            }
            //  taskId 任务ID 和 openIdOrDevId groupId msgId url 的对应关系存储在Video的 Redis中, 用于回调处理.
            String[] split = value.split("&");
            String openIdOrDevId = split[0];
            String groupId = split[1];
            String msgId = split[2];
            //检测对象的URL
            String sourceUrl = split[3];

            JSONObject data = content.getJSONObject("Data");
            JSONArray sliceDetails = data.getJSONArray("SliceDetails");

            for (int i = 0; i < sliceDetails.size(); i++) {
                JSONObject item = sliceDetails.getJSONObject(i);
                //如果违规,把标准的语音文件替换原有的违规语音的URL地址
                String labels = item.getString("Labels");
                //是否确认为敏感 (是否违规)
                boolean isSensitiveness = false;
                if (!StringUtils.isEmpty(labels)) {
                    String[] labelsList = labels.split(",");
                    //表示命中的标签
                    JSONArray m_labels = JSONArray.parseArray("[\"violence\",\"political_content\",\"specified_speaking\",\"specified_lyrics\",\"sexual_content\",\"sexual_sounds\",\"contraband\",\"profanity\",\"religion\",\"cyberbullying\"]");
                    for (int j = 0; j < labelsList.length; j++) {
                        String label = labelsList[j];
                        if (m_labels.contains(label)) {
                            //命中上面列出的标签
                            isSensitiveness = true;
                        }
                    }

                    if (isSensitiveness) {
                        // 记录审核失败统计
                        messageStatsService.updateError(openIdOrDevId);

                        userKeyActionService.add(10, openIdOrDevId, "用户:" + openIdOrDevId + " 微聊语音: 敏感词违规 groupId:" + groupId + " msgId:" + msgId + " url:" + sourceUrl);
                        log.info("用户:" + openIdOrDevId + " 微聊语音: 敏感词违规 groupId:" + groupId + " msgId:" + msgId + " url:" + sourceUrl);
                        //把标准的语音文件替换原有的违规语音的URL地址
                        String[] urlSplit = sourceUrl.split(BaseBucketTool.MESSAGE_COMMON_PATH);
                        try {
                            String fileName = urlSplit[1];
                            ClassPathResource resource = new ClassPathResource("outLineVoice.amr");
                            InputStream inputStream = resource.getInputStream();
                            baseBucketTool.upload(BaseBucketTool.MESSAGE_COMMON_PATH + fileName, inputStream, 2);
                        } catch (Exception e) {
                            log.error("把标准的语音文件替换原有的违规语音的URL地址 时报错, e:" + e.getMessage(), e);
                        }
                        break;
                    }
                }
            }

        } catch (Exception e) {
            log.error("阿里云内容安全回调接口-语音 接口处理报错:error:" + e.getMessage(), e);
        }


        return ResponseMap.success();
    }

    public static void main(String[] args) {
        //checksum=d705bbe6b09a072266be02a145c60f759fbccbd21a3975a3410e579af1652d16
        String checksum = "d705bbe6b09a072266be02a145c60f759fbccbd21a3975a3410e579af1652d16";
        String aliuid = "xxx";
        String seed = "jianyou";
        String encodedContent = "";
        String combined = aliuid + seed + encodedContent;
        byte[] hash = hashWithSHA256(combined);

        System.out.println("new checksum :" + bytesToHex(hash));


    }
}
